package myJs.user.soft

import myJs.Implicits._
import myJs.Utils._

import scala.scalajs.js.Dynamic.{global => g}
import myJs.myPkg.bootstrap.Bootstrap.default._
import myJs.myPkg.jquery._
import myJs.myPkg.{ColumnOptions, LayerOptions}
import myJs.tool.Pojo._
import myJs.tool.Tool
import myJs.tool.Tool._
import org.scalajs.dom._
import org.scalajs.dom.ext.{Ajax, KeyCode}
import scalatags.Text.all._
import shared.Pojo._
import shared._

import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import scala.scalajs.js
import scala.scalajs.js.Date
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}

/**
 * Created by yz on 2019/4/25
 */
@JSExportTopLevel("SoftCenter")
object SoftCenter {

  case class SoftData(name: String, showName: String, intro: String, heart: Int, updateTime: Date)

  def softF = {
    val url = g.jsRoutes.controllers.SoftController.getAllSoft().url.toString
    Ajax.get(url = s"${url.noCache}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      val softMap = xhr.responseText.toJArJDJAn.toMyJDS.map { dict =>
        val showName = Tool.messages.getOrElse(dict("name"), dict("showname"))
        SoftData(dict("name"), showName, "", dict("heart").toInt, new Date(dict("updateTime")))
      }.toList.filterNot { x =>
        val hideSofts = List(BiomarkerSoft)
        hideSofts.map(_.nameStr).contains(x.name)
      }.map { x =>
        (x.name, x)
      }.toSeqMap
      val sortedNames = sortedSofts.map(_.nameStr)
      sortedNames.map { nameStr =>
        softMap(nameStr)
      }
    }
  }

  def collectF = {
    val url = g.jsRoutes.controllers.CollectController.getCollect().url.toString
    Ajax.get(url = s"${url.noCache}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      xhr.responseText.toJArS
    }
  }

  @JSExport("init")
  def init = {
    registerEvent
    refreshSoft
  }

  def refreshSoft = {
    val searchSoftF = softF.map { softs =>
      val keyword = Tool.getInputByName("keyword").myVal
      val filterSofts = softs.filter { x =>
        x.showName.containsIgnoreCase(keyword)
      }
      filterSofts
    }
    searchSoftF.zip(collectF).map { case (softs, collects) =>
      val kind = $(".fc-state-active").text().trim
      val kindSofts = kind match {
        case x if x==messages("myCollection") => softs.filter { soft => collects.contains(soft.name) }
        case _ => softs
      }
      val html = {
        if (kindSofts.isEmpty) {
          val str = kind match {
            case x if x==messages("myCollection") => messages("YouHaveNotFavorited")
            case _ => messages("NoRelatedModulesFound")
          }
          div(textAlign := "center", marginBottom := 20,
            str
          ).render
        } else {
          kindSofts.map { soft =>
            val url = Tool.getUrl(soft.name)
            val isCollect = collects.contains(soft.name)
            val faHeart = if (isCollect) {
              "fa-heart"
            } else "fa-heart-o"
            val titleStr = if (isCollect) messages("cancelFavorite") else messages("AddToFavorites")
            val fileName = soft.name match {
              case x if List(PcaSoft.nameStr, DiffAnaSoft.nameStr, BoxplotSoft.nameStr, ViolinPlotSoft.nameStr).
                contains(x) => s"${x}.png"
              case x => s"${x}.png"
            }
            div(`class` := "col-sm-4",
              div(`class` := "mt-comment",
                div(`class` := "mt-comment-img",
                  a(href := url,
                    img(src := s"/assets/images/${fileName}", width := 90))
                ),
                div(`class` := "mt-comment-body",
                  div(minHeight:=90,
                    div(`class` := "mt-comment-info",
                      span(`class` := "mt-comment-author",
                        a(href := url, soft.showName)
                      )
                    ),
                    div(`class` := "mt-comment-text", soft.intro),
                  ),
                  div(`class` := "mt-comment-details",
                    ul(`class` := "mt-comment-actions",
                      li(
                        i(`class` := s"fa ${faHeart} myHeart", dataName := soft.name, attr("data-placement") := "left",
                          attr("data-toggle") := "tooltip", title := s"${titleStr}"
                        ), s"${soft.heart}"
                      ))
                  )
                )
              )
            )
          }.mkString("")
        }
      }
      $("#soft").html(html)
      $("[data-toggle='tooltip']").tooltip()
    }
  }

  def registerEvent = {
    $(document.body).on("click", ".mySearch", "", (y: Element) => {
      refreshSoft
    })
    $(document.body).on("keyup", ".mySearchInput", "", (y: Element, e: Event) => {
      val event = e.asInstanceOf[KeyboardEvent]
      if (event.keyCode == KeyCode.Enter) {
        refreshSoft
      }
    })
    $(document.body).on("mouseover", ".myHeart", "", (y: Element) => {
      $(y).toggleClass("fa-heart-o fa-heart")
    })
    $(document.body).on("mouseout", ".myHeart", "", (y: Element) => {
      $(y).toggleClass("fa-heart-o fa-heart")
    })
    $(document.body).on("click", ".myHeart", "", (y: Element) => {
      if ($(y).hasClass("fa-heart")) {
        collect(y)
      } else unCollect(y)
    })
    $(document.body).on("click", ".mySort", "", (y: Element) => {
      refreshSoft
    })
    $(document.body).on("click", ".fc-month-button", "", (y: Element) => {
      $(".fc-month-button").removeClass("fc-state-active")
      $(y).addClass("fc-state-active")
      refreshSoft
    })
  }

  def collect(y: Element) = {
    val name = $(y).dataName
    val url = g.jsRoutes.controllers.SoftController.collect().url.toString
    Ajax.get(url = s"${url.noCache}&name=${name}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      refreshSoft.map { x =>
        layer.msg(s"${messages("addSuccessfully")}", LayerOptions.icon(0).time(2000))
      }
    }
  }

  def unCollect(y: Element) = {
    val name = $(y).dataName
    val url = g.jsRoutes.controllers.SoftController.unCollect().url.toString
    Ajax.get(url = s"${url.noCache}&name=${name}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      refreshSoft.map { x =>
        layer.msg(s"${messages("cancelSuccessfully")}", LayerOptions.icon(0).time(2000))
      }
    }
  }

}
